package com.ce.source.analysis.hashmap;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ：xiaopingzhang8@creditease.cn
 * @Description ：HashMap源码分析
 * @ClassName ：HashMapAnalyse
 * @Company ：普信恒业科技发展（北京）有限公司
 * @date ：2017/11/22 12:26
 */
public class HashMapAnalyse {

    public static void main(String[] args) {
        analyseResize();
    }

    /**
     * <p>
     * 1.首先初始化HashMap,根据传入的Capacity(容量)默认为16,load_factor(负载因子)0.75
     * 临界值threshold=Capacity*load_factor
     * 2.插入数据时：
     * 1）根据key计算hash值
     * 2）根据hash值和（Capacity-1）做位与&运算，计算索引，使数据平均散落到各个索引
     * 3）根据索引i获取值e=table[i]
     * 3.1）e==null 插入数据
     * 3.1.1）首先判断size>=threshold(临界值)&&null != table[i])
     * 如果为真：
     * >扩容的容量大小=2*Capacity
     * >数据重排transfer
     * >计算hash插入数据
     * 否则：
     * 插入数据
     * 如果table[i]!=nul
     * 则以链表的形式插入数据
     * size++
     * <p>
     * 3.2)e!=null
     * 3.2.1)判断e.hash == hash && ((k = e.key) == key || key.equals(k))
     * 如果为真：
     * 替换
     * 否则：
     * 继续3.1.1的步骤
     * <p>
     * </p>
     * 分析HashMap扩容
     */
    public static void analyseResize() {
        Map<Object, Object> map = new HashMap<Object, Object>(4);
//        map.put("a", "data-a");
        map.put("b", "data-b");
//        map.put("c", "data-c");
        map.put("97", "data-97");
        map.put(98, "data-98");
        map.put(97, "date-65");
        System.out.println(map.get(97));
//        map.remove("a");
//        map.remove("b");

    }

    /**
     * <p>
     *     1.首先根据key计算hash值
     *     2.根据hash&table.length-1 计算索引
     *     3.根据table[i]获取entry
     *          3.1）判断当前entry是不是需要的
     *              如果是：
     *                  return e
     *              如果不是：
     *                  entry=entry.next 遍历链表
     * </p>
     * 分析HashMap获取数据
     */
    public static void analyseGet() {
        Map<Object, Object> map = new HashMap<Object, Object>(4);
        map.put("a", "data-a");
        map.put("b", "data-b");
        map.put("c", "data-c");
        map.put(97, "date-65");
        System.out.println(map.get("a"));
    }
}
